<?php

declare (strict_types=1);
/**
 * @copyright 深圳市易果网络科技有限公司
 * @version 1.0.0
 * @link https://dayiguo.com
 */

namespace App\Service\Agent;


use App\Dao\AgentDao;
use App\Dao\BusinessDao;
use App\Dao\LocationDao;
use App\Dao\PlatformOrderDao;
use App\Dao\UserDao;
use App\Kernel\Util\AgentJwtInstance;
use App\Service\Service;

use Hyperf\Di\Annotation\Inject;

/**
 * 渠道商服务
 *
 *
 * @author 张昊(2396675557@qq.com)
 * @package App\Service\Admin
 */
class ChannelService extends Service
{
    /**
     * @Inject
     * @var UserDao
     */
    public $user_dao;

    /**
     * @Inject
     * @var LocationDao
     */
    public $location_dao;

    /**
     * 商家Dao
     * @Inject()
     * @var BusinessDao
     */
    public $business_dao;

    /**
     * @Inject
     * @var AgentDao
     */
    public $agent_dao;

    /**
     * 产品订单Dao
     * @Inject()
     * @var PlatformOrderDao
     */
    public $platform_order_dao;

    /**
     * 合伙人直招区代下面的渠道商
     */
    public function getPartnerChannel()
    {
        $agent = AgentJwtInstance::instance()->build()->getAgent();

        if( $agent['identity'] == 1 || $agent['identity'] == 2 || $agent['identity'] == 3) {
            $this->error("COMMON.HANDLE_FAILED");
        }

        $agentData = $this->agent_dao->mapMany([
            'inviter_id' => $agent['id'],
            'identity' => 1,
        ],false);

        $ids = [];
        foreach ($agentData as $item) {
            $ids[] = $item['location_id'];
        }

        $map = [
            'district_id' => ['in',$ids],
            'group_id' => 2,
        ];

        $result = $this->user_dao->areaAgent($map);

        $data = [];
        $data['list'] = [];
        if( $result ) {
            foreach ($result as $key => $value) {
                $data['list'][$key]['id'] = $value['id'];
                $data['list'][$key]['phone'] = $value['phone'];
                $data['list'][$key]['name'] = $value['name'];
                $data['list'][$key]['address'] = $value['province'].$value['city'].$value['district'];
                $data['list'][$key]['belonging'] = $value['district'];
                $data['list'][$key]['pay_time'] = "";
                $business_count = $this->business_dao->count([
                    'parent_id' => $value['id'],
                    'status' => 1,
                ]);
                $user_count = $this->user_dao->count([
                    'parent_id' => $value['id'],
                    'group_id' => 1,
                ]);
                $data['list'][$key]['share_user'] = $user_count;
                $data['list'][$key]['share_store'] = $business_count;
                $data['list'][$key]['commission'] = 0;
            }
        }
        $data['agent_channel_count'] = $this->user_dao->count($map);

        return $data;
    }

    /**
     * 获得该分公司下的所有的区
     * @return mixed
     */
    public function getDirectDistricts()
    {
        $agent = AgentJwtInstance::instance()->build()->getAgent();

        if( $agent['identity'] == 1 || $agent['identity'] == 2 ) {
            $this->error("COMMON.HANDLE_FAILED");
        }

        $map = [];

        $map['inviter_id'] = $agent['id']; // 邀请人ID
        $map['identity'] = 1; // 区代身份

        $agents = $this->agent_dao->getAgentsByMap($map, null, ['id', 'inviter_id', 'identity', 'location_id'])->toArray();
        $location_ids = array_column($agents, 'location_id');
        $locations = $this->location_dao->getLocationsByMap(['pid' => ['in',$location_ids]])->toArray();

        return $locations;
    }

    /**
     * 获得该分公司下所有合伙人的所有区
     */
    public function getPartnerDistricts()
    {
        $agent = AgentJwtInstance::instance()->build()->getAgent();

        if( $agent['identity'] == 1 || $agent['identity'] == 2 ) {
            $this->error("COMMON.HANDLE_FAILED");
        }

        $map = [];

        $map['inviter_id'] = $agent['id']; // 邀请人ID
        $map['identity'] = 4; // 市场合伙人

        $agents = $this->agent_dao->getAgentsByMap($map, null, ['id'])->toArray();
        $partner_ids = array_column($agents, 'id');

        $area_map = [];
        $area_map['inviter_id'] = ['in', $partner_ids];
        $area_map['identity'] = 1; // 区代理
        $areas = $this->agent_dao->getAgentsByMap($area_map, null, ['location_id'])->toArray();
        $location_ids = array_column($areas, 'location_id');
        $locations = $this->location_dao->getLocationsByMap(['pid' => ['in',$location_ids]])->toArray();
        return $locations;

    }


    /**
     * 公司渠道商
     */
    public function companyChannel()
    {
        $agent = AgentJwtInstance::instance()->build()->getAgent();

        if( $agent['identity'] == 1 || $agent['identity'] == 2 ) {
            $this->error("COMMON.HANDLE_FAILED");
        }

        $agentData = $this->agent_dao->mapMany([
            'inviter_id' => $agent['id'],
            'identity' => 1,
        ],false);

        $ids = [];
        foreach ($agentData as $item) {
            $ids[] = $item['location_id'];
        }

        $map = [
            'district_id' => ['in',$ids],
            'group_id' => 2,
        ];

        $result = $this->user_dao->areaAgent($map);

        $data = [];
        if( $result ) {
            foreach ($result as $key => $value) {
                $data['list'][$key]['id'] = $value['id'];
                $data['list'][$key]['phone'] = $value['phone'];
                $data['list'][$key]['name'] = $value['name'];
                $data['list'][$key]['address'] = $value['province'].$value['city'].$value['district'];
                $data['list'][$key]['belonging'] = $value['district'];
                $data['list'][$key]['pay_time'] = "";
                $business_count = $this->business_dao->count([
                    'parent_id' => $value['id'],
                    'status' => 1,
                ]);
                $user_count = $this->user_dao->count([
                    'parent_id' => $value['id'],
                    'group_id' => 1,
                ]);
                $data['list'][$key]['share_user'] = $user_count;
                $data['list'][$key]['share_store'] = $business_count;
                $data['list'][$key]['commission'] = 0;
            }
        }
        $data['agent_channel_count'] = $this->user_dao->count($map);

        return $data;
    }

    /**
     * 直招区代理下的渠道商
     * @param array $params
     * @return mixed
     */
    public function directChannelList(array $params)
    {
        $locations = $this->getDirectDistricts();
        $district_ids = array_column($locations, 'pid');
        $map['group_id'] = 2; // 渠道商
        if (isset($params['district_id'])) {
            if (!in_array($params['district_id'], $district_ids)) { // 不在合伙人范围内
                $map['district_id'] = ['in', []];
                $page_size = 10;
                $channel_list = $this->user_dao->getUsersByMap($map, null, ['id', 'district_id', 'name', 'phone'], $page_size)->toArray();
                return $channel_list;
            } else {
                $map['district_id'] = (int)$params['district_id'];
                $map = $this->map($map, $params);

                $sort = 'created_at desc';
                $page_size = 10;
                $select = ['id', 'district_id', 'name', 'phone', 'province', 'city', 'district'];

                $channel_list = $this->user_dao->getUsersByMap($map, $sort, $select, $page_size)->toArray();
                $channel_list['data'] = $this->joinShareData($channel_list['data']);
                return $channel_list;
            }

        } else { // 没传district_id的情况
            $map['district_id'] = ['in', $district_ids]; // 区范围
            $map = $this->map($map, $params);

            $sort = 'created_at desc';
            $page_size = 10;
            $select = ['id', 'district_id', 'name', 'phone', 'province', 'city', 'district'];

            $channel_list = $this->user_dao->getUsersByMap($map, $sort, $select, $page_size)->toArray();
            $channel_list['data'] = $this->joinShareData($channel_list['data']);

            return $channel_list;

        }

    }

    /**
     * 公司合伙人招的区代理下的
     * @param array $params
     * @return mixed
     */
    public function partnerChannelList(array $params)
    {
        $locations = $this->getPartnerDistricts();
        $district_ids = array_column($locations, 'pid');
        $map['group_id'] = 2; // 渠道商
        if (isset($params['district_id'])) {
            if (!in_array($params['district_id'], $district_ids)) { // 不在合伙人范围内
                $map['district_id'] = ['in', []];
                $page_size = 10;
                $channel_list = $this->user_dao->getUsersByMap($map, null, ['id', 'district_id', 'name', 'phone'], $page_size)->toArray();
                return $channel_list;
            } else {
                $map['district_id'] = (int)$params['district_id'];
                $map = $this->map($map, $params);

                $sort = 'created_at desc';
                $page_size = 10;
                $select = ['id', 'district_id', 'name', 'phone', 'province', 'city', 'district'];

                $channel_list = $this->user_dao->getUsersByMap($map, $sort, $select, $page_size)->toArray();
                $channel_list['data'] = $this->joinShareData($channel_list['data']);
                return $channel_list;
            }

        } else { // 没传district_id的情况
            $map['district_id'] = ['in', $district_ids]; // 区范围
            $map = $this->map($map, $params);

            $sort = 'created_at desc';
            $page_size = 10;
            $select = ['id', 'district_id', 'name', 'phone', 'province', 'city', 'district'];

            $channel_list = $this->user_dao->getUsersByMap($map, $sort, $select, $page_size)->toArray();
            $channel_list['data'] = $this->joinShareData($channel_list['data']);

            return $channel_list;

        }

    }


    /**
     * 拼接分享数的数据
     * @param array $channel_list
     * @return array
     */
    public function joinShareData(array $channel_list)
    {
        $ids = array_column($channel_list, 'id');
        $selectRaw = 'parent_id, count(CASE WHEN group_id=1 THEN parent_id END) as member_num';
        $biz_selectRaw = 'parent_id, count(CASE WHEN status=1 THEN parent_id END) as business_num';
        $group_by = 'parent_id';

        $shares = $this->user_dao->getSelectRawByIds($ids, $selectRaw, $group_by); // 会员
        $members = $shares->pluck('member_num', 'parent_id')->toArray();

        $biz_shares = $this->business_dao->getSelectRawByIds($ids, $biz_selectRaw, $group_by); // 商家
        $businesses = $biz_shares->pluck('business_num', 'parent_id')->toArray();
        // 支付时间
        $plat_orders = $this->platform_order_dao->getOrdersByMap([
            'user_id' => ['in', $ids],
            'product_id' => 1, // 升级渠道商
            'status' => 1, // 已支付状态
        ], ['user_id', 'created_at']);

        $pay_times = $plat_orders->pluck('created_at', 'user_id')->toArray();

        foreach ($channel_list as &$item) {
            $item['share_user'] = $members[$item['id']]??0; // 分享会员数
            $item['share_store'] = $businesses[$item['id']]??0; // 分享商家数
            $item['address'] = $item['province'].$item['city'].$item['district']; // 地址
            $item['belonging'] = $item['district']; // 地区
            $item['pay_time'] = isset($pay_times[$item['id']])?date("Y-m-d", (int)$pay_times[$item['id']]):""; // 升级时间
        }

        return $channel_list;
    }

    /**
     * 合伙人渠道商
     */
    public function partnerChannel()
    {
        $agent = AgentJwtInstance::instance()->build()->getAgent();

        if( $agent['identity'] == 1 || $agent['identity'] == 2 ) {
            $this->error("COMMON.HANDLE_FAILED");
        }

        $partner = $this->agent_dao->mapMany([
            'inviter_id' => $agent['id'],
            'identity' => 4,
        ],false);

        $partner_id = [];
        foreach ( $partner as $item ) {
            $partner_id[] = $item['id'];
        }

        $agentData = $this->agent_dao->mapMany([
            'inviter_id' => ['in',$partner_id],
            'identity' => 1,
        ],false);

        $ids = [];
        foreach ($agentData as $item) {
            $ids[] = $item['location_id'];
        }

        $map = [
            'district_id' => ['in',$ids],
            'group_id' => 2,
        ];

        $result = $this->user_dao->areaAgent($map);

        $data = [];
        if( $result ) {
            foreach ($result as $key => $value) {
                $data['list'][$key]['id'] = $value['id'];
                $data['list'][$key]['phone'] = $value['phone'];
                $data['list'][$key]['name'] = $value['name'];
                $data['list'][$key]['address'] = $value['province'].$value['city'].$value['district'];
                $data['list'][$key]['belonging'] = $value['district'];
                $data['list'][$key]['pay_time'] = "";
                $business_count = $this->business_dao->count([
                    'parent_id' => $value['id'],
                    'status' => 1,
                ]);
                $user_count = $this->user_dao->count([
                    'parent_id' => $value['id'],
                    'group_id' => 1,
                ]);
                $data['list'][$key]['share_user'] = $user_count;
                $data['list'][$key]['share_store'] = $business_count;
                $data['list'][$key]['commission'] = 0;
            }
        }
        $data['agent_channel_count'] = $this->user_dao->count($map);

        return $data;
    }

    /**
     * 代理商渠道商列表
     */
    public function list()
    {
        $user = AgentJwtInstance::instance()->build()->getAgent();

        $map = [];
        $address = '';
        switch ($user['identity']) {
            case "1": //区
                $map = [
                    'district_id' => $user['location_id'],
                    'group_id' => 2,
                ];
                $province = $this->location_dao->getLocationByPid( [
                    'pid' => $user['location_id']
                ] );

                $city = $this->location_dao->getLocationByPid( [
                    'pid' => $province['level']
                ] );

                $district = $this->location_dao->getLocationByPid( [
                    'pid' => $city['level']
                ] );
                $address = $district['name'].$city['name'].$province['name'];
                break;
            case "2": //市
                $map = [
                    'city_id' => $user['location_id'],
                    'group_id' => 2,
                ];

                $city = $this->location_dao->getLocationByPid( [
                    'pid' => $user['location_id']
                ] );

                $district = $this->location_dao->getLocationByPid( [
                    'pid' => $city['level']
                ] );
                $address = $district['name'].$city['name'];
                break;
        }

        $result = $this->user_dao->areaAgent($map);

        $data = [];
        if( $result ) {
            foreach ($result as $key => $value) {
                $data['list'][$key]['id'] = $value['id'];
                $data['list'][$key]['phone'] = $value['phone'];
                $data['list'][$key]['name'] = $value['name'];
                $data['list'][$key]['address'] = $value['province'].$value['city'].$value['district'];
                $data['list'][$key]['pay_time'] = "";
                $business_count = $this->business_dao->count([
                    'parent_id' => $value['id'],
                    'status' => 1,
                ]);
                $user_count = $this->user_dao->count([
                    'parent_id' => $value['id'],
                    'group_id' => 1,
                ]);
                $data['list'][$key]['share_user'] = $user_count;
                $data['list'][$key]['share_store'] = $business_count;
                $data['list'][$key]['commission'] = 0;
            }
        }

        $data['agent_address'] = $address;
        $data['agent_type'] = $user['identity'];
        $data['agent_channel_count'] = $this->user_dao->count($map);

        return $data;
    }

    /**
     * 获取渠道商列表
     * @param array $params
     * @return array|mixed
     */
    public function getChannelList(array $params)
    {

        $user = AgentJwtInstance::instance()->build()->getAgent();

        $map = [];
        $address = '';
        switch ($user['identity']) {
            case "1": //区
                $map = [
                    'district_id' => $user['location_id'],
                    'status' => 1,
                ];
                $province = $this->location_dao->getLocationByPid( [
                    'pid' => $user['location_id']
                ] );

                $city = $this->location_dao->getLocationByPid( [
                    'pid' => $province['level']
                ] );

                $district = $this->location_dao->getLocationByPid( [
                    'pid' => $city['level']
                ] );
                $address = $district['name'].$city['name'].$province['name'];
                break;
            case "2": //市
                $map = [
                    'city_id' => $user['location_id'],
                    'status' => 1,
                ];

                $city = $this->location_dao->getLocationByPid( [
                    'pid' => $user['location_id']
                ] );

                $district = $this->location_dao->getLocationByPid( [
                    'pid' => $city['level']
                ] );
                $address = $district['name'].$city['name'];
                break;
        }
        $data['agent_business_count'] = $this->user_dao->count($map);
        $data['agent_address'] = $address;
        $data['agent_type'] = $user['identity'];

        $map['group_id'] = 2; //渠道商

        isset($params['district_id']) && !empty($params['district_id']) && $map['district_id'] = $params['district_id']; // 区

        // 更多搜索条件
        $map = $this->map($map, $params);

        $sort = 'created_at desc';
        $select = ['id', 'created_at', 'name', 'phone', 'group_id', 'province', 'city', 'district', 'city', 'province'];
        $page_size = 10;
        $channel_list = $this->user_dao->getUsersByMap($map,$sort, $select, $page_size)->toArray();
        $channel_list = array_merge($data, $channel_list);

        $channel_list['data'] = $this->joinData($channel_list['data']);

        return $channel_list;
    }

    /**
     * 拼接数据
     * @param array $channel_list
     * @return mixed
     */
    public function joinData(array $channel_list)
    {
        foreach ($channel_list as &$item) {
            $item['created_at'] = date('Y.m.d',(int)$item['created_at']);
            $item['address'] = $item['province'].$item['city'].$item['district'];
            $item['share_user'] = $this->user_dao->count(['parent_id'=> $item['id'], 'group_id' => 1]); // 分享会员的数量
            $item['share_store'] = $this->business_dao->count(['parent_id' => $item['id']]); // 返佣
            $item['commission'] = 0; // 返佣
        }
        return $channel_list;
    }

    /**
     * 赋值查询条件
     * @param array $map
     * @param array $params
     * @return array
     */
    public function map(array $map, array $params)
    {
        switch ($params['select']??1) {
            case 1: // 时间范围
                isset($params['start_time']) && !isset($params['end_time'])  && !empty($params['start_time']) && $map['created_at'] = ['>=', strtotime($params['start_time'])]; // 下单开始时间
                isset($params['end_time']) &&  !isset($params['start_time'])  && !empty($params['end_time']) && $map['created_at'] = ['<=', strtotime($params['end_time'])]; // 下单结束时间

                isset($params['end_time']) &&  isset($params['start_time']) &&
                !empty($params['end_time']) && !empty($params['start_time']) &&
                $map['between_field'] = ['created_at' =>[strtotime($params['start_time']), strtotime($params['end_time'])]]; // 有下单开始和结束时间
                break;
            case 2:
                $params['now_date'] = $params['now_date']??3;
                if ($params['now_date'] == 1) { // 本日
                    // 本日开始
                    $first = date('Y-m-d 00:00:00', time());
                    $first = strtotime($first);
                    // 本日结束
                    $last = date('Y-m-d 23:59:59', time());
                    $last = strtotime($last);
                } elseif ($params['now_date'] == 2) { // 本月
                    // 本月第一天
                    $first = date('Y-m-01 00:00:00', time());
                    // 本月最后一天
                    $last = date('Y-m-d 23:59:59', strtotime("$first +1 month -1 day"));
                    $last = strtotime($last);
                    $first = strtotime($first);

                } else { // 本年
                    // 本年第一天
                    $first = date('Y-01-01 0:0:0', time());
                    $first = strtotime($first);
                    // 本年最后一天
                    $last = date('Y-12-31 23:59:59', time());
                    $last = strtotime($last);
                }
                $map['between_field'] = ['created_at' => [$first, $last]];

                break;
            case 3:
                isset($params['search']) && !empty($params['search'])
                && $map['or_field'] = [
                    'name' => ['like', "%{$params['search']}%"],
                    'phone' => ['like', "%{$params['search']}%"],
                ];
                break;
            default:
                $this->error("未选择查询");
                break;
        }

        return $map;
    }





}